package main

import (
	"fmt"
	"time"
)

func NewWorkManager(workers []string, fn func(name string, storage *[]int) Job) *WorkManager {
	return &WorkManager{
		Workers:     workers,
		newJobFunc:  fn,
		runningJobs: []Job{},
		AllResults:  []int{},
		printed:     []int{},
	}
}

type WorkManager struct {
	Workers     []string
	newJobFunc  func(name string, storage *[]int) Job
	runningJobs []Job
	AllResults  []int
	printed     []int
}

// Goroutine initiation functions
func (w *WorkManager) Start(processNumber int) {
	wp := NewWorkerPool(processNumber)
	wp.Run()
	go func() {
		for i := range w.Workers {
			job := w.newJobFunc(w.Workers[i], &w.AllResults)
			w.runningJobs = append(w.runningJobs, job)
			wp.JobQueue <- job
		}
	}()
}

// Like a wait function. This function must be called, otherwise the program will simply exit.
func (w *WorkManager) Wait() {
	for {
		time.Sleep(time.Millisecond * 400)
		isBreak := true
		// Completion check function
		for i := range w.runningJobs {
			if !w.runningJobs[i].IsFinish() {
				isBreak = false
			}
		}

		// Print result, does not affect main program
		for i := range w.AllResults {
			if !IntInSlice(w.AllResults[i], w.printed) {
				fmt.Println("Get result:", w.AllResults[i])
				w.printed = append(w.printed, w.AllResults[i])
			}
		}

		// Finish check
		if isBreak {
			break
		}
	}
}
